#ifndef DATA_CODEC_H
#define DATA_CODEC_H

#include <vector>
#include <cstdint>
#include <memory>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <iostream>

/**
 * DataCodec 类
 * 功能：用于流数据的编码和解码，支持粘包处理和超时机制
 * 版本：1.0
 * 作者：Gavin
 */
typedef struct
{
    uint16_t header;   // 数据包同步码，固定值0x55AA
    uint16_t len;      // 数据包总长度
    uint16_t crc;      // 校验和（累加计算，排除crc字段）
    uint16_t seq;      // 序列号
    uint16_t cmd;      // 命令
    uint16_t data_len; // 数据长度
    uint8_t data[0];   // 数据
} pkt_t;

// 日志级别枚举
enum class LogLevel
{
    NONE,
    ERROR,
    INFO,
    DEBUG
};

// 编解码类
class DataCodec
{
public:
    DataCodec(LogLevel log_level = LogLevel::INFO);
    ~DataCodec();

    // 编码函数
    std::vector<uint8_t> encode(const pkt_t &packet, const uint8_t *data);

    // 解码函数
    std::vector<std::unique_ptr<pkt_t>> decode(const std::vector<uint8_t> &data_stream);

    // 设置日志级别
    void set_log_level(LogLevel log_level);

private:
    enum class State
    {
        WAIT_FOR_HEADER,
        READ_LENGTH,
        READ_PAYLOAD
    };

    State state;                                             // 当前状态
    std::vector<uint8_t> buffer;                             // 缓冲区
    size_t buffer_pos;                                       // 缓冲区当前位置
    const int timeout_ms;                                    // 超时时间（毫秒）
    std::chrono::steady_clock::time_point last_state_change; // 上次状态变化的时间戳
    std::thread timeout_thread;                              // 超时检查线程
    std::atomic<bool> running;                               // 线程运行标志
    std::mutex mtx;                                          // 互斥量保护共享数据
    std::condition_variable cv;                              // 条件变量用于通知超时检查线程
    LogLevel log_level;                                      // 日志级别

    // 超时检查线程函数
    void timeout_checker();

    // 重置状态机
    void reset_state_machine();

    // 检查超时
    void check_timeout();

    // 更新状态并记录时间戳
    void update_state(State new_state);

    // 处理字节的状态机函数
    void process_byte(uint8_t byte, std::vector<std::unique_ptr<pkt_t>> &packets);

    // 计算校验和
    uint16_t calculate_crc(const uint8_t *data, size_t length);

    // 日志函数
    void log(LogLevel level, const std::string &message);
};

#endif // DATA_CODEC_H
